package com.ruoyi.products.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.wx.pay.WxPayConfig;
import com.ruoyi.common.config.wx.pay.WxPayInfo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.products.domain.BussCoupons;
import com.ruoyi.products.domain.BussOrder;
import com.ruoyi.products.mapper.BussCouponsMapper;
import com.ruoyi.products.mapper.BussOrderMapper;
import com.ruoyi.products.service.IBussOrderService;
import com.ruoyi.products.service.IWxPayService;
import com.ruoyi.system.mapper.SysUserMapper;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.util.*;

@RequiredArgsConstructor
@Service
@Slf4j
public class WxPayServiceImpl implements IWxPayService {
    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final Random RANDOM = new SecureRandom();

    @Autowired
    private BussOrderMapper bussOrderMapper;

    @Autowired
    private BussCouponsMapper bussCouponsMapper;

    @Autowired
    private IBussOrderService bussOrderService;
    @Autowired
    private TokenService tokenService;


    @Autowired
    private SysUserMapper userMapper;
    //配置微信支付
    @Autowired
    private WxPayConfig wxPayConfig;
    //微信专业httpClient
    private static CloseableHttpClient httpClient;
    //生成签名用
    private static Sign sign;
    //证书管理器
    private static CertificatesManager certificatesManager;

    @PostConstruct
    public void init() throws Exception {
        //获取商户私钥
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(getFileInputStream(wxPayConfig.getCertKeyPath()));
        // 获取证书管理器实例
        certificatesManager = CertificatesManager.getInstance();
        sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, merchantPrivateKey.getEncoded(), null);
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(wxPayConfig.getMerchantId(),
                new WechatPay2Credentials(wxPayConfig.getMerchantId(),
                        new PrivateKeySigner(wxPayConfig.getMerchantSerialNumber(), merchantPrivateKey)),
                wxPayConfig.getApiV3Key()
                        .getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(wxPayConfig.getMerchantId());
        //用于构造HttpClient
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(wxPayConfig.getMerchantId(), wxPayConfig.getMerchantSerialNumber(), merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier));
        httpClient = builder.build();
    }

    /**
     * 使用getResourceAsStream直接从resources根路径下获取文件流
     *
     * @param path
     */
    private InputStream getFileInputStream(String path) {
        InputStream in = this.getClass().getResourceAsStream(path);
        return in;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxPayInfo createOrder(BussOrder bo) throws IOException {

        //查询套餐的信息
        Long couponsId = bo.getCouponsId(); //套餐id
        BussCoupons bussCoupons = bussCouponsMapper.selectBussCouponsById(couponsId);
        //创建订单
        String orderNumber = getOrderNumber();

        JSONObject obj = new JSONObject();
        JSONObject map = new JSONObject();
        //套餐id
        map.put("couponsId", couponsId);
        obj.put("attach", map.toJSONString());

        obj.put("appid", wxPayConfig.getAppId());
        obj.put("mchid", wxPayConfig.getMerchantId());
        //设置订单过期时间 3分钟后 自动过期 3 × 60 × 1000 = 180000
        obj.put("time_expire", DateUtils.toExpirationTime(180000L)); //订单3分钟后自动过期


//        //套餐描述
        obj.put("description", bussCoupons.getCouponsInfo());
        //订单信息
        obj.put("out_trade_no", orderNumber);
//        //线上地址
        obj.put("notify_url", wxPayConfig.getWxnotify());
        JSONObject amount = new JSONObject();
        //获取订单的金额  计算单位 为 分
        amount.put("total", bussCoupons.getPrice().multiply(new BigDecimal(100)).longValue());
        obj.put("amount", amount);
        JSONObject payer = new JSONObject();
//        //支付者的openId 信息
        payer.put("openid", bo.getOpenId());
        obj.put("payer", payer);
        log.info("请求参数为：" + JSON.toJSONString(obj));
        //执行请求
        JSONObject jsonResult = sendHttpPost(obj, "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
        String prePayId = jsonResult.getString("prepay_id");
        if (prePayId == null) {
            String message = jsonResult.getString("message");
            throw new ServiceException(message);
        }
        WxPayInfo wxPayInfo = new WxPayInfo();
        wxPayInfo.setAppId(wxPayConfig.getAppId());
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        wxPayInfo.setTimeStamp(timeStamp);
        String nonceStr = IdUtil.fastSimpleUUID();
        wxPayInfo.setNonceStr(nonceStr);
        wxPayInfo.setPrepay_id(prePayId);
        String packageStr = "prepay_id=" + prePayId;
        wxPayInfo.setPackageStr(packageStr);
        wxPayInfo.setSignType("RSA");
        String signString = wxPayConfig.getAppId() + "\n" + timeStamp + "\n" + nonceStr + "\n" + packageStr + "\n";
        wxPayInfo.setPaySign(Base64.encode(sign.sign(signString.getBytes())).toString());

        return wxPayInfo;
    }


    /**
     * 支付回调通知处理
     *
     * @param
     * @return
     * @throws
     */
    @Override
    public Map parseOrderNotifyResult(HttpServletRequest servletRequest) {
        HashMap<String, Object> map = new HashMap<>();
        String timeStamp = servletRequest.getHeader("Wechatpay-Timestamp");
        String nonce = servletRequest.getHeader("Wechatpay-Nonce");
        String signature = servletRequest.getHeader("Wechatpay-Signature");
        String certSn = servletRequest.getHeader("Wechatpay-Serial");
        JSONObject notifyResult;
        Long stuUserId = null;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(servletRequest.getInputStream()))) {
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            String obj = stringBuilder.toString();
            log.info("回调数据:{},{},{},{},{}", obj, timeStamp, nonce, signature, certSn);
            Verifier verifier = certificatesManager.getVerifier(wxPayConfig.getMerchantId());
            String sn = verifier.getValidCertificate().getSerialNumber().toString(16).toUpperCase(Locale.ROOT);
            NotificationRequest request = new NotificationRequest.Builder().withSerialNumber(sn)
                    .withNonce(nonce)
                    .withTimestamp(timeStamp)
                    .withSignature(signature)
                    .withBody(obj)
                    .build();
            NotificationHandler handler = new NotificationHandler(verifier, wxPayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
            // 验签和解析请求体
            Notification notification = handler.parse(request);
            log.info("notification.getDecryptData():" + notification.getDecryptData());
            notifyResult = JSON.parseObject(notification.getDecryptData());
            log.info("notifyResult:" + notifyResult);
            Map payer = (Map) notifyResult.get("payer");
            String openid = String.valueOf(payer.get("openid"));
            String attach = String.valueOf(notifyResult.get("attach"));
            JSONObject.parseObject(attach);
            JSONObject jsonObject = JSONObject.parseObject(attach);
            //套餐id
            Long couponsId = jsonObject.getLong("couponsId");
            BussCoupons bussCoupons = bussCouponsMapper.selectBussCouponsById(couponsId);

            //更具 open ID 查询用户
            SysUser sysUser = userMapper.selectWxUserByOpenId(openid);

            //查询当前用户
            if (sysUser == null) {
                throw new ServiceException("用户不存在");
            }

            Date menberTime = sysUser.getMenberTime();
            // 没有充值过                    或者会员已过期
            if (menberTime == null || menberTime.getTime() < new Date().getTime()) {
                menberTime = new Date();
            }
            //增加延续 vip
            menberTime.setTime(menberTime.getTime() + bussCoupons.getDaysToAdd() * 24 * 60 * 60 * 1000);

            sysUser.setMenberTime(menberTime);

            //首次充值
            handleUserCoupons(sysUser, bussCoupons);
          /*
            if (userCouponsId == null) {
                sysUser.setCouponsId(couponsId);
            } else {

                //判断会员是否过期
                if (sysUser.getMenberTime().getTime() < new Date().getTime()) {
                    //如果过期 赋值当前套餐
                    sysUser.setCouponsId(couponsId);
                } else {
                    //如果是续费 判断套餐  下载次数的
                    if (userCouponsId == couponsId) {
                        //如果参数没有变化续费即可 无需修改


                    } else if (userCouponsId != couponsId) {
                        //查询当前的用户套餐
                        BussCoupons userCoupons = bussCouponsMapper.selectBussCouponsById(userCouponsId);
                        //如果用户套餐下载次数大于新套餐下载次数  --- 无需更换
                        if (userCoupons.getDayCount() > bussCoupons.getDayCount()) {
                            // 无需更换
                        } else {
                            //更换套餐
                            sysUser.setCouponsId(couponsId);
                        }

                    }

                }

            }
*/

            userMapper.updateUser(sysUser);
            //订单信息 需要存入数据库 todo
            BussOrder order = new BussOrder();

            order.setOrderNo(notifyResult.getString("out_trade_no"));
            order.setCouponsId(couponsId);
            order.setOpenId(openid);
            order.setTransactionType("微信支付");
//            order.setPaymentBank("");
            //获取金额 amount 详情
            Map amountMap = (Map) notifyResult.get("amount");
            order.setOrderAmount(new BigDecimal(String.valueOf(amountMap.get("payer_total"))));
            order.setPaymentType("0");
            order.setThirdOrderNo(notifyResult.getString("transaction_id"));//三方订单号
            order.setPaymentCompletionTime(notifyResult.getDate("success_time"));
            bussOrderService.insertBussOrder(order);

            //            order.setIsRefund("");
//            order.setRefundId("");
//            order.setOutRefundNo("");

            log.info(notifyResult.toString());

            map.put("code", 200);
            map.put("msg", "success");
            return map;  // 返回 success 表示处理成功

        } catch (Exception e) {
            log.error("微信支付回调失败", e);
            log.info(e.getMessage());
            map.put("code", "FAIL");
            map.put("message", "失败");
            return map;  // 出现异常也返回 fail，避免微信重复推送
        }
    }

    private void handleUserCoupons(SysUser sysUser, BussCoupons bussCoupons) {
        Long userCouponsId = sysUser.getCouponsId();
        Long couponsId = bussCoupons.getId();

        if (userCouponsId == null) {
            sysUser.setCouponsId(couponsId);
        } else if (isMemberExpired(sysUser)) {
            sysUser.setCouponsId(couponsId);
        } else if (userCouponsId.equals(couponsId)) {
            // 同一套餐，无需更改
        } else {
            updateIfBetterPackage(sysUser, userCouponsId, couponsId, bussCoupons);
        }
    }

    private boolean isMemberExpired(SysUser sysUser) {
        return sysUser.getMenberTime() == null || sysUser.getMenberTime().getTime() < new Date().getTime();
    }

    private void updateIfBetterPackage(SysUser sysUser, Long userCouponsId, Long couponsId, BussCoupons newCoupon) {
        BussCoupons userCoupon = bussCouponsMapper.selectBussCouponsById(userCouponsId);
        if (userCoupon != null && userCoupon.getDayCount() < newCoupon.getDayCount()) {
            sysUser.setCouponsId(couponsId);
        }
    }




    /**
     * 微信退款
     *
     * @param bo
     * @return
     * @throws Exception
     */
//    @Override
//    @Transactional
//    public String refund(@RequestBody StuOrderBo bo) throws IOException {
//        if (StringUtils.isEmpty(bo.getThirdOrderNo()) || StringUtils.isEmpty(bo.getOrderNo())) {
//            throw new ServiceException("商户订单号 和 微信订单号不可为空");
//        }
//        //退款
//        JSONObject obj = new JSONObject();
//        obj.put("transaction_id", bo.getThirdOrderNo());
//        String outRefundNo = getOrderNumber();
//        obj.put("out_refund_no", outRefundNo); //退款的单号
//        JSONObject amount = new JSONObject();
//        //查询订单需要退款的金额
//        StuOrderVo stuOrderVo = iStuOrderService.getByOrderNo(bo.getOrderNo());
//        BigDecimal total = stuOrderVo.getOrderAmount();
//        amount.put("refund", total.intValue());
//        amount.put("total", total.intValue());
//        amount.put("currency", "CNY");
//        obj.put("amount", amount);
//        //废除物品 学生下的所有物品
//        //查询学生拥有的所有物品进行废除
//        StuUserProjectBo stuUserProjectBo = new StuUserProjectBo();//查询条件更具当前用户进行查询
//        stuUserProjectBo.setStuOrderId(stuOrderVo.getId());
//        List<StuUserProjectVo> stuUserProjectVos = iStuUserProjectService.queryList(stuUserProjectBo);
//        //校验是否已领取的物品
//        for (StuUserProjectVo o : stuUserProjectVos) {
//            if (StuUserConstants.PROJECT_STATE_RECEIVE.equals(o.getProjectState())) {
//                //查询物品名称
//                throw new ServiceException(iProjectService.queryById(o.getProjectId()).getProjectName() + "该物品已领取，请归还后再退款！");
//            }
//        }
//        stuUserProjectBo.setProjectState(StuUserConstants.PROJECT_STATE_ABROGATE);
//
//        JSONObject refundObject = sendHttpPost(obj, "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds");
//        String refund_id = refundObject.getString("refund_id");
//        if (StringUtils.isEmpty(refund_id)) {
//            String message = refundObject.getString("message");
//            throw new ServiceException(message);
//        }
//        //查询订单
//        stuOrderVo.setRefundId(refund_id);
//        stuOrderVo.setOutRefundNo(outRefundNo);
//        stuOrderVo.setIsRefund("1");
//
//
//        iStuUserProjectService.updateProJectState(stuUserProjectBo);
//        //准备小程序端的请求参数 修改订单信息
//        iStuOrderService.updateByBo(BeanUtil.toBean(stuOrderVo, StuOrderBo.class));
//        return refund_id;
//    }

    /**
     * 查询 微信支付订单
     */
//    @Override
//    public JSONObject queryWxOrder(Long stuUserId) throws IOException, URISyntaxException {
//        StuOrderVo stuOrderVo = RedisUtils.getCacheObject(CacheConstants.STU_ORDER_KEY + stuUserId);
//        if (ObjectUtils.isEmpty(stuOrderVo)) {
//            throw new ServiceException("订单不存在");
//        }
//        //请求URL
//        URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + stuOrderVo.getOrderNo());
//        uriBuilder.setParameter("mchid", wxPayConfig.getMerchantId());
//        //完成签名并执行请求
//        HttpGet httpGet = new HttpGet(uriBuilder.build());
//        httpGet.addHeader("Accept", "application/json");
//        CloseableHttpResponse response = httpClient.execute(httpGet);
//        try {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                //   log.info("success,return body = " + EntityUtils.toString(response.getEntity()));
//                return JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
//            } else if (statusCode == 204) {
//                return JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
//            }
//            throw new ServiceException(EntityUtils.toString(response.getEntity()));
//        } finally {
//            response.close();
//        }
//    }

    /**
     * 查询 微信支付订单
     *
     * @throws Exception
     */
//    @Override
//    public JSONObject queryByOrderNo(String orderNo) throws IOException, URISyntaxException {
//        //请求URL
//        URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + orderNo);
//        uriBuilder.setParameter("mchid", wxPayConfig.getMerchantId());
//        //完成签名并执行请求
//        HttpGet httpGet = new HttpGet(uriBuilder.build());
//        httpGet.addHeader("Accept", "application/json");
//        CloseableHttpResponse response = httpClient.execute(httpGet);
//        try {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                return JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
//            } else if (statusCode == 204) {
//                return JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
//            }
//            throw new ServiceException(EntityUtils.toString(response.getEntity()));
//
//        } finally {
//            response.close();
//        }
//    }

    /**
     * 关闭微信支付订单
     *
     * @throws Exception
     */

//    @Override
//    public String CloseWxOrder(Long stuUserid) throws IOException {
//        StuOrderVo stuOrderVo = iStuOrderService.getByStuUserIdOrder(stuUserid);
//        WxPayInfo wxPayInfo = stuOrderVo.getWxPayInfo();
//        if (ObjectUtils.isEmpty(wxPayInfo)) {
//            RedisUtils.deleteKeys(CacheConstants.STU_ORDER_KEY + stuUserid);
//            return "已经删除 商家的订单";
//        }
//        //请求URL
//        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + stuOrderVo.getOrderNo() + "/close");
//        //请求body参数
//        String reqdata = "{\"mchid\": \"" + wxPayConfig.getMerchantId() + "\"}";
//        StringEntity entity = new StringEntity(reqdata, "utf-8");
//        entity.setContentType("application/json");
//        httpPost.setEntity(entity);
//        httpPost.setHeader("Accept", "application/json");
//        //完成签名并执行请求
//        CloseableHttpResponse response = httpClient.execute(httpPost);
//        try {
//            int statusCode = response.getStatusLine().getStatusCode();
//            if (statusCode == 200) {
//                log.info("success,return body = " + EntityUtils.toString(response.getEntity()));
//                RedisUtils.deleteKeys(CacheConstants.STU_ORDER_KEY + stuUserid);
//                return "订单关闭成功";
//            } else if (statusCode == 204) {
//                RedisUtils.deleteKeys(CacheConstants.STU_ORDER_KEY + stuUserid);
//                return "订单关闭成功";
//            }
//            //  throw new ServiceException(EntityUtils.toString(response.getEntity()));
//            return "关闭订单异常";
//        } catch (IOException e) {
//            throw new ServiceException(e.getMessage());
//        } finally {
//            RedisUtils.deleteKeys(CacheConstants.STU_ORDER_KEY + stuUserid);
//            response.close();
//        }
//    }


    //凭证调用
    private JSONObject getAccessToken() throws Exception {
        //小程序APPID
        String appid = wxPayConfig.getAppId();//自行获取
        //小程序secret
        String secret = wxPayConfig.getAppSecret();//自己去公众号后台获取
        String httpUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
        String res = "";
        httpUrl = httpUrl + "&appid=" + appid + "&secret=" + secret;
        return sendHttpGet(httpUrl);
    }

    //生成小程序跳转链接
//    @Override
//    public String getAppletUrl(Long stuUserId) throws Exception {
//        //接口地址
//        String httpUrl = "https://api.weixin.qq.com/wxa/generatescheme?access_token=";
//        //需要跳转的小程序路径
//        String path = "pages/index/index";
//        String newUrl = "";
//        //获取AccessToken
//        //   String AccessTokenJson=getAccessToken();
//        //格式化返回数据
//        JSONObject resultObject = getAccessToken();
//        String AccessToken = resultObject.getString("access_token");
//        if (AccessToken == null) {
//            throw new ServiceException("AccessToken 不存在" + resultObject.getString("errmsg"));
//        } else {
//            try {
//                String content = "";
//                JSONObject jsonParam = new JSONObject();
//                JSONObject jump_wxa = new JSONObject();
//                jump_wxa.put("path", path);
//                jump_wxa.put("query", "userId=" + stuUserId);
//                jump_wxa.put("env_version", "develop");//正式版直接注释掉
//                jsonParam.put("jump_wxa", jump_wxa);
//                jsonParam.put("expire_type", 1);
//                jsonParam.put("expire_interval", 2);
//                String params = jsonParam.toString();
//                CloseableHttpClient httpClient = HttpClients.createDefault();
//                RequestConfig requestConfig = RequestConfig.custom()
//                    .setSocketTimeout(300 * 1000)
//                    .setConnectTimeout(300 * 1000)
//                    .build();
//                HttpPost post = new HttpPost(httpUrl + AccessToken);
//                post.setConfig(requestConfig);
//                post.setHeader("Content-Type", "application/json;charset=utf-8");
//                //URLEncoder.encode(name)
//                StringEntity postingString = new StringEntity(params, "utf-8");
//                post.setEntity(postingString);
//                CloseableHttpResponse response = httpClient.execute(post);
//                content = EntityUtils.toString(response.getEntity());
//                JSONObject resultUrl = JSONObject.parseObject(content);
//                newUrl = resultUrl.getString("openlink");
//                log.info("WeChatInterfaceUtil.getWeixinUrl--" + newUrl);
//            } catch (SocketTimeoutException e) {
//                e.printStackTrace();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        return newUrl;
//    }

    @Override
    public Map getWxConfig(String stuUserId) throws Exception {
        Map<String, String> map = new HashMap<>();
        String access_token = "";
        //拼接地址获取token
        JSONObject token = sendHttpGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxPayConfig.getAppId() + "&secret=" + wxPayConfig.getAppSecret());
        access_token = token.getString("access_token");
        //获取jsapi
        JSONObject jsapiStr = sendHttpGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi");
        String jsapi_ticket = jsapiStr.getString("ticket");
        /*****************获取签名signature********************/
        //生成随机字符串  noncestr
        String nonceStr = UUID.randomUUID().toString();
        //时间戳 timestamp，精确到秒
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        //url
        String url = "https://www.amybelle.cc/openlink/" + stuUserId;
        String Stitching = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url;
        log.info("Stitching：" + Stitching);
        //SHA1 加密
        java.security.MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
        digest.update(Stitching.getBytes());
        byte messageDigest[] = digest.digest();
        StringBuffer hexStr = new StringBuffer();
        // 字节数组转换为 十六进制 数
        for (int i = 0; i < messageDigest.length; i++) {
            String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
            if (shaHex.length() < 2) {
                hexStr.append(0);
            }
            hexStr.append(shaHex);
        }
        map.put("appId", wxPayConfig.getAppId());
        map.put("timestamp", timestamp);
        map.put("nonceStr", nonceStr);
        map.put("signature", hexStr.toString());
        return map;
    }

    @Override
    public void paySuccess(String openid) {
        SysUser sysUser = userMapper.selectWxUserByOpenId(openid);

        LoginUser loginUser = SecurityUtils.getLoginUser();
        //修改用户的 会员时间
        loginUser.getUser().setMenberTime(sysUser.getMenberTime());
        //刷新套餐id
        SysUser user = loginUser.getUser();
        user.setCouponsId(sysUser.getCouponsId());
        loginUser.setUser(user);

        //修改登录时间
        tokenService.setLoginUser(loginUser);
    }

    private JSONObject sendHttpPost(JSONObject obj, String url) {
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
        httpPost.setEntity(new StringEntity(obj.toJSONString(), "UTF-8"));
        try {
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String bodyAsString = EntityUtils.toString(response.getEntity());
            JSONObject jsonResult = JSONObject.parseObject(bodyAsString);
            return jsonResult;
        } catch (IOException e) {
            log.info(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    private JSONObject sendHttpGet(String url) throws Exception {
        //请求URL
        URIBuilder uriBuilder = new URIBuilder(url);
        uriBuilder.setParameter("mchid", wxPayConfig.getMerchantId());
        //完成签名并执行请求
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        httpGet.addHeader("Accept", "application/json");
        CloseableHttpResponse response = httpClient.execute(httpGet);
        JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
        jsonObject.put("code", response.getStatusLine().getStatusCode());
        return jsonObject;
    }

    /**
     * 生产订单号
     *
     * @return
     */
    private String getOrderNumber() {
        return UUID.randomUUID().toString().replace("-", "");
    }

}
